/*!
 * \file type_datetime.h
 * \author Fabien Arcellier (fabien_arcellier@yahoo.fr)
 * \version 1.0
 * 
 * This file contains a data type to encode and manipulate date and time.
 */

/*! \brief Call to malloc instruction has failed
 */
#define DATETIME_OPERATION_SUCCESS 0
#define DATETIME_ERROR_1_MALLOC_INIT_FAILED 1

/*! \brief This struct contains date and time information
 */
typedef struct datetime
{
  int year;
  int month;
  int day;
  int hour;
  int minute;
  int second;
  int msecond;
} DATETIME;

typedef DATETIME * PTR_DATETIME;

/*! \brief Create a new instance of an object DATETIME.
 *  \return 0 if success, otherwise an error code
 * 
 * All Fields are initiate at zero.
 */
int DATETIME_Create(PTR_DATETIME *ptrDateTime);

/*! \brief Destroy an instance of an object DATETIME
 *  \return 0 if success, otherwise an error code
 * 
 * ptrDateTime is set at NULL
 */
int DATETIME_Destroy(PTR_DATETIME *ptrDateTime);

/*! \brief Compare two instances of DateTime
 * \return 1 if ptrDateTime1 is after ptrDateTime2, 0 if ptrDateTime1 == ptrDateTime2, otherwise -1
 */
int DATETIME_Compare(PTR_DATETIME ptrDateTime1, PTR_DATETIME ptrDateTime2);

/*! \brief Get date information from an instance of DATETIME
 *  \return 0 if success, otherwise an error code
 */
int DATETIME_GetDate(PTR_DATETIME ptrDateTime, int *year, int *month, int *day);

/*! \brief Set date information to an instance of DATETIME
 *  \return 0 if success, otherwise an error code
 */
int DATETIME_SetDate(PTR_DATETIME ptrDateTime, int year, int month, int day);

/*! \brief Add one or many days to an instance of a DateTime
 * \return 0 if success otherwise error code
 * 
 * If nbDay is negative, the instance of datetime go to the past.
 */
int DATETIME_AddDay(PTR_DATETIME ptrDateTime, int nbDay);

/*! \brief Add one or many months to an instance of a DateTime
 * \return 0 if success otherwise error code
 * 
 * If nbMonth is negative, the instance of datetime go to the past.
 */
int DATETIME_AddMonth(PTR_DATETIME ptrDateTime, int nbMonth);

/*! \brief Add one or many year to an instance of a DateTime
 * \return 0 if success otherwise error code
 * 
 * If nbYear is negative, the instance of datetime go to the past.
 */
int DATETIME_AddYear(PTR_DATETIME ptrDateTime, int nbYear);

/*! \brief Verify a date is valid
 *  \return 0 if valid, otherwise 1
 * 
 * Check :
 * - Month value is between 1 and 12
 * - Day value is between 0 and 31
 * - Day value is valid in relation with Month and Date (if Month has 28, 29 or 30 days)
 */
int DATETIME_IsDateValid(int year, int month, int day);

/*! \brief Verify the invariant of a DateTime structure. Should return 1 if invariant is valid, otherwise 0
 * 
 */
int DATETIME_CheckInvariant(PTR_DATETIME ptrDateTime);

/*! \brief Get the number of day in the month specified
 * \return the number of day, that is to say 28, 29, 30 or 31
 */
int DATETIME_GetDaysInMonth(int year, int month);